<template>
  <div>
    <div class="tree-item" :class="{show:item.show}" v-for="item in showData" :key="item[prop.id]">
      <div class="list-item" @click="handleItemClick(item)"
           @contextmenu="handleItemContextmenu(item)">
        <div class="tree-node">
          <div class="expand-icon"
               @click.stop="expandSt(item)"
               :class="{
            show:item[prop.children]&&item[prop.children].length,
               expanded:item.expanded}"></div>
          <div>{{ item[prop.label] }}</div>
        </div>
      </div>
      <div v-show="item.expanded" class="children-box">
        <my-tree ref="myTree"
                 :filter-node-method="filterNodeMethod"
                 @item-click="handleItemClick"
                 @item-contextmenu="handleItemContextmenu"
                 :data="item[prop.children]"
                 :props="props"/>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "MyTree",
  props: {
    filterNodeMethod: {
      type: Function,
      default: () => (() => true)
    },
    data: {
      type: Array,
      default: () => ([])
    },
    props: {
      type: Object,
      default: () => ({})
    }
  },
  data () {
    return {
      prop: {
        id: 'id',
        label: 'label',
        children: 'children'
      },
      filterValue: ''
    }
  },
  computed: {
    showData () {
      this.data.forEach(item => {
        if (!this.filterValue) this.$set(item, 'show', true)
        let children = item[this.prop.children]
        let hasChildren = !!(children && (children.find(it => it.show)))
        let show = this.filterNodeMethod(this.filterValue, item) || hasChildren
        return this.$set(item, 'show', show)
      });
      return this.data
    }
  },
  mounted () {
    for (let key in this.props) {
      if (this.props[key]) {
        this.prop[key] = this.props[key]
      }
    }
  },
  methods: {
    filter (value) {
      this.data.forEach(item => {
        let trees = this.$refs.myTree
        trees.forEach(tree => tree.filter(value))
      })
      this.filterValue = value
    },
    expandSt (item) {
      let idName = this.prop.id
      let it = this.data.find(_item => _item[idName] === item[idName])
      if (it) this.$set(it, 'expanded', !item.expanded)
    },
    handleItemClick (item) {
      this.$emit('item-click', item)
    },
    handleItemContextmenu (item) {
      this.$emit('item-contextmenu', item)
    }
  }
}
</script>

<style scoped lang="scss">
.tree-item {
  border-top: 1px solid #e2e0e0;
  display: none;

  &:nth-child(1) {
    border-top: 0;
  }

  .tree-node {
    display: flex;
    align-items: center;

    .expand-icon {
      width: 28px;
      height: 28px;
      visibility: hidden;
      margin-right: 10px;
      background-image: url("~@/assets/svg/jiantou.svg");
      background-repeat: no-repeat;
      background-position: center;
      transition-duration: 0.3s;

      &.show {
        visibility: visible;
      }

      &.expanded {
        transform: rotate(90deg);
      }

      &:hover {
        background-color: rgba(0, 0, 0, 0.05)
      }
    }
  }

  &.show {
    display: block;
  }
}

</style>
